package com.gupaoedu.vip;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <p>
 *
 * </p>
 *
 * @author Nicky
 * @since 2019/11/18
 */
@Component
public class GpRpcServer implements ApplicationContextAware, InitializingBean {

  ExecutorService executorService = Executors.newCachedThreadPool();

  private int port;

  private Map<String,Object> handlerBeanMap = new HashMap<>();

  public GpRpcServer(int port) {
    this.port = port;
  }

  //设置属性是调用
  @Override
  public void afterPropertiesSet() throws Exception {
    ServerSocket serverSocket = null;

    try {
      serverSocket = new ServerSocket(port); //BIO模型
      //不断接受请求
      while (true){
        Socket socket = serverSocket.accept();
        executorService.execute(new ProcesserHander(socket,handlerBeanMap));

      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    finally {
      if(serverSocket != null){
        try {
          serverSocket.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    Map<String,Object> serviceMapBean =  applicationContext.getBeansWithAnnotation(RpcService.class);
    for(Object serviceBean:serviceMapBean.values()){
      //拿到注解
      RpcService rpcService = serviceBean.getClass().getAnnotation(RpcService.class);
      //得到注解中的值
      String serviceName = rpcService.value().getName();
      handlerBeanMap.put(serviceName,serviceBean);
    }
  }
}
